#pragma once

#include <iostream>
#include <string>
#include <functional>
#include <vector>
#include <list>
#include <memory>
#include <thread>

using namespace std;

#define     TEST_UNIQUEPTRANDSHAREPTR           0

/**
 * @brief The Object class                  智能指针对象，注意: 是对象不是指针
 */

namespace UniqueAndSharePtr
{
    class Object
    {
    public:
        Object()
        {
            std::cout << "Object() - " << this << endl;
        }

        ~Object()
        {
            std::cout << "~Object() - " << this << endl;
        };

        void add(int a, int b)
        {
            std::cout << a << " + " << b <<" = " << a+b << endl;
        }

        void mul(int a, int b)
        {
            std::cout << a << " + " << b <<" = " << a+b << endl;
        }

        int m_num = 1;
        string m_str;
    };


    class Abs
    {
    public:
        Abs()
        {
            std::cout << "Abs() - " << this << endl;
        }
        ~Abs()
        {
            std::cout << "~Abs() - " << this << endl;
        }
    };


    class AbsObj
    {
    public:
        AbsObj()
        {
            std::cout << "AbsObj() - " << this << endl;
            m_ptr.reset(new Abs());
        }

        AbsObj(AbsObj &obj)
        {
            cout << "Copy AbsObj";
        }

        AbsObj &operator=(const Abs &obj)
        {
            cout << "AbsObj operator=";
            return (*this);
        }

        ~AbsObj()
        {
            std::cout << "~AbsObj() - " << this << endl;
        }

        // 初始化列表
        void initVec()
        {
            for ( auto i=0; i<5; i++ )
            {
                unique_ptr<Abs> ptr(new Abs);
                m_ptrVec.push_back(std::move(ptr));             // 直接使用变量，避免拷贝赋值
            }
        }

        unique_ptr<Abs> m_ptr;
        vector<unique_ptr<Abs>> m_ptrVec;               // 智能指针列表

    };
}


// 智能指针对象做返回值
unique_ptr<UniqueAndSharePtr::Object> getPtr()
{
    unique_ptr<UniqueAndSharePtr::Object> unptr(new UniqueAndSharePtr::Object);
    std::cout << "unptr: " << &unptr << endl;
    return unptr;
}

// 智能指针对象做引用参数
void updateInfo(unique_ptr<UniqueAndSharePtr::Object> &&obj, int num, const string &str)
{
    obj->m_num = num;
    obj->m_str = str;
}


// 智能指针对象做参数
void printInfo(const unique_ptr<UniqueAndSharePtr::Object> &obj)
{
    std::cout << "Num: " << obj->m_num << " | Str: " << obj->m_str;
}









